package com.doubao.hardware.service.impl;

import com.doubao.hardware.entity.HardwareDeviceEntity;
import com.doubao.hardware.mapper.HardwareDeviceMapper;
import com.doubao.hardware.mapper.HardwaresmartDeviceMappe;
import com.doubao.hardware.service.DeviceHardwareService;
import com.doubao.hardware.service.MqttService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import jakarta.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 设备-智能体关联服务实现类
 * 负责处理硬件设备与智能体之间的交互
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class DeviceHardwareServiceImpl implements DeviceHardwareService {

    private final HardwareDeviceMapper hardwareDeviceMapper;
    private final HardwaresmartDeviceMappe smartDeviceMapper;
    private final MqttService mqttService;
    private final ObjectMapper objectMapper;
    private final RestTemplate restTemplate;

    // 记录设备的最后配置，避免重复发送
    private final Map<String, String> deviceConfigCache = new ConcurrentHashMap<>();

    @Value("${mqtt.baidu.topic:$iot/Albot_Config/user/ai}")
    private String mqttTopic;

    @Value("${api.device.base-url:http://localhost:8001}")
    private String deviceServiceBaseUrl;

    @Override
    public boolean configureDeviceAI(String macAddress, Long smartDeviceId) {
        // 默认不强制更新
        return configureDeviceAI(macAddress, smartDeviceId, false);
    }

    @Override
    public boolean configureDeviceAI(String macAddress, Long smartDeviceId, boolean forceUpdate) {
        try {
            // 1. 获取硬件设备信息
            HardwareDeviceEntity hardwareDevice = hardwareDeviceMapper.selectByMacAddress(macAddress);
            if (hardwareDevice == null) {
                log.error("未找到指定MAC地址的设备: {}", macAddress);
                return false;
            }

            // 2. 获取智能体信息
            Map<String, Object> smartDevice = getSmartDeviceInfo(smartDeviceId);
            if (smartDevice == null) {
                log.error("未找到指定ID的智能体: {}", smartDeviceId);
                return false;
            }

            // 3. 格式化MAC地址(确保格式一致)
            String formattedMac = formatMacAddress(macAddress);

            // 4. 构建MQTT消息
            Map<String, Object> deviceConfig = new HashMap<>();
            deviceConfig.put("hardware_device_wuid", hardwareDevice.getProductId());

            // 使用智能体表中的原始字段名，并直接按照MQTT需要的格式映射
            deviceConfig.put("api_key", smartDevice.get("api_key"));
            deviceConfig.put("url", smartDevice.get("api_base_url"));
            deviceConfig.put("endpoint", smartDevice.get("ai_model_id"));
            deviceConfig.put("voice_type", smartDevice.get("voice_type"));

            // 将 voice_speed_ratio 转换为字符串
            Object voiceSpeedRatio = smartDevice.get("voice_speed_ratio");
            deviceConfig.put("voice_speed_ratio", voiceSpeedRatio != null ? String.valueOf(voiceSpeedRatio) : "1");
            deviceConfig.put("name", smartDevice.get("name"));

            // 记录发送的配置信息
            log.debug("设备配置信息: api_key={}, endpoint={}, url={}, voice_type={}",
                    deviceConfig.get("api_key"),
                    deviceConfig.get("endpoint"),
                    deviceConfig.get("url"),
                    deviceConfig.get("voice_type"),
                    deviceConfig.get("voice_speed_ratio"),
                    deviceConfig.get("name"));

            Map<String, Object> mqttPayload = new HashMap<>();
            mqttPayload.put(formattedMac, deviceConfig);

            // 5. 计算配置的哈希值，检查是否与上次相同
            String configJson = objectMapper.writeValueAsString(mqttPayload);
            String configHash = String.valueOf(configJson.hashCode());

            String lastHash = deviceConfigCache.get(formattedMac);

            // 增加 forceUpdate 参数判断，强制更新时跳过配置哈希检查
            if (configHash.equals(lastHash) && !forceUpdate) {
                log.info("设备 {} 的配置未变更，跳过发送", formattedMac);

                // 即使跳过发送，也要确保设备数据库记录已更新
                if (hardwareDevice.getSmartDeviceId() == null || !hardwareDevice.getSmartDeviceId().equals(smartDeviceId)) {
                    hardwareDevice.setSmartDeviceId(smartDeviceId);
                    hardwareDeviceMapper.updateById(hardwareDevice);
                    log.info("更新设备 {} 的智能体ID为 {}", formattedMac, smartDeviceId);
                }

                return true;
            }

            // 6. 发送MQTT消息
            log.info("发送智能体配置到设备 {}: {}", formattedMac, configJson);
            boolean success = mqttService.sendMessage(configJson);

            if (success) {
                // 更新缓存
                deviceConfigCache.put(formattedMac, configHash);

                // 更新设备的智能体关联
                hardwareDevice.setSmartDeviceId(smartDeviceId);
                hardwareDeviceMapper.updateById(hardwareDevice);

                log.info("设备 {} 成功配置为智能体 {}", formattedMac, smartDeviceId);
                return true;
            } else {
                log.error("发送MQTT消息失败");
                return false;
            }

        } catch (Exception e) {
            log.error("配置设备AI失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    public void clearDeviceCache(String macAddress) {
        String formattedMac = formatMacAddress(macAddress);
        deviceConfigCache.remove(formattedMac);
        log.info("已清除设备 {} 的配置缓存", formattedMac);
    }

    @Override
    public boolean clearDeviceAI(String macAddress) {
        try {
            // 获取硬件设备信息
            HardwareDeviceEntity hardwareDevice = hardwareDeviceMapper.selectByMacAddress(macAddress);
            if (hardwareDevice == null) {
                log.error("未找到指定MAC地址的设备: {}", macAddress);
                return false;
            }

            // 格式化MAC地址
            String formattedMac = formatMacAddress(macAddress);

            // 构建空的配置
            Map<String, Object> deviceConfig = new HashMap<>();
            deviceConfig.put("hardware_device_wuid", hardwareDevice.getProductId());
            deviceConfig.put("api_key", "");
            deviceConfig.put("url", "");
            deviceConfig.put("endpoint", "");
            deviceConfig.put("voice_type", "");
            deviceConfig.put("voice_speed_ratio", "");
            deviceConfig.put("name", "");

            Map<String, Object> mqttPayload = new HashMap<>();
            mqttPayload.put(formattedMac, deviceConfig);

            String configJson = objectMapper.writeValueAsString(mqttPayload);

            // 发送MQTT消息
            boolean success = mqttService.sendMessage(configJson);

            if (success) {
                // 移除缓存
                deviceConfigCache.remove(formattedMac);

                // 更新设备的智能体关联为null
                hardwareDevice.setSmartDeviceId(null);
                hardwareDeviceMapper.updateById(hardwareDevice);

                log.info("设备 {} 的智能体配置已清除", formattedMac);
                return true;
            } else {
                log.error("发送MQTT消息失败");
                return false;
            }

        } catch (Exception e) {
            log.error("清除设备AI配置失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    public Long getCurrentSmartDeviceId(String macAddress) {
        try {
            HardwareDeviceEntity hardwareDevice = hardwareDeviceMapper.selectByMacAddress(macAddress);
            if (hardwareDevice == null) {
                return null;
            }
            return hardwareDevice.getSmartDeviceId();
        } catch (Exception e) {
            log.error("获取设备当前智能体ID失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 格式化MAC地址，确保使用冒号分隔且全小写
     */
    private String formatMacAddress(String macAddress) {
        if (macAddress == null) {
            return "";
        }

        // 移除所有分隔符
        String mac = macAddress.replaceAll("[:-]", "").toLowerCase();

        // 如果已经是规范格式，直接返回
        if (macAddress.contains(":") && macAddress.length() == 17) {
            return macAddress.toLowerCase();
        }

        // 插入冒号
        StringBuilder formattedMac = new StringBuilder();
        for (int i = 0; i < mac.length(); i++) {
            if (i > 0 && i % 2 == 0) {
                formattedMac.append(':');
            }
            formattedMac.append(mac.charAt(i));
        }

        return formattedMac.toString();
    }

    /**
     * 获取当前请求的认证头
     */
    private String getAuthorizationHeader() {
        try {
            // 从上下文中获取当前请求
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                return request.getHeader("Authorization");
            }
        } catch (Exception e) {
            log.warn("获取认证头失败: {}", e.getMessage());
        }
        return null;
    }

    /**
     * 从数据库获取智能体信息
     */
    private Map<String, Object> getSmartDeviceInfo(Long deviceId) {
        log.info("获取智能体信息: id={}", deviceId);

        try {
            // 首先尝试从数据库直接查询智能体信息
            Map<String, Object> smartDevice = smartDeviceMapper.selectById(deviceId);

            if (smartDevice != null && !smartDevice.isEmpty()) {
                log.info("从数据库查询到智能体信息: {}", smartDevice);

                // 如果数据库字段使用驼峰命名，转换为下划线命名
                Map<String, Object> formattedDevice = new HashMap<>();
                formattedDevice.put("id", deviceId);
                formattedDevice.put("api_key", smartDevice.get("api_key"));
                formattedDevice.put("api_base_url", smartDevice.get("api_base_url"));
                formattedDevice.put("ai_model_id", smartDevice.get("ai_model_id"));
                formattedDevice.put("voice_type", smartDevice.get("voice_type"));
                formattedDevice.put("voice_speed_ratio", smartDevice.get("voice_speed_ratio"));
                formattedDevice.put("name", smartDevice.get("name"));

                log.info("使用来自数据库的智能体信息: api_key={}, ai_model_id={}, voice_type={}",
                        formattedDevice.get("api_key"),
                        formattedDevice.get("ai_model_id"),
                        formattedDevice.get("voice_type"));

                return formattedDevice;
            }

            // 如果数据库中没有找到，尝试从远程API获取
            log.info("数据库中未找到智能体信息，尝试从API获取");

            try {
                // 获取认证头
                String authHeader = getAuthorizationHeader();
                if (authHeader == null) {
                    log.warn("未找到认证头，将使用默认智能体配置");
                    return createDefaultSmartDevice(deviceId);
                }

                String url = deviceServiceBaseUrl + "/device/" + deviceId;
                log.info("调用设备服务获取智能体信息: {}", url);

                // 创建HTTP头，添加JWT令牌
                HttpHeaders headers = new HttpHeaders();
                headers.set("Authorization", authHeader);

                // 创建HTTP实体
                HttpEntity<String> entity = new HttpEntity<>(headers);

                // 使用exchange方法，传递HTTP头
                ResponseEntity<Map> response = restTemplate.exchange(
                        url,
                        HttpMethod.GET,
                        entity,
                        Map.class
                );

                Map<String, Object> responseBody = response.getBody();
                if (responseBody != null && responseBody.containsKey("code") && (Integer) responseBody.get("code") == 200) {
                    // 返回数据部分
                    Map<String, Object> apiSmartDevice = (Map<String, Object>) responseBody.get("data");
                    if (apiSmartDevice == null || apiSmartDevice.isEmpty()) {
                        log.error("API返回智能体信息成功但数据为空");
                        return createDefaultSmartDevice(deviceId);
                    }

                    // API返回的响应可能使用了驼峰命名法，需要转换成下划线分隔
                    Map<String, Object> formattedDevice = new HashMap<>();
                    formattedDevice.put("id", apiSmartDevice.get("id"));

                    // 尝试从驼峰格式获取，如果为空则从下划线格式获取
                    formattedDevice.put("api_key", getValue(apiSmartDevice, "apiKey", "api_key"));
                    formattedDevice.put("api_base_url", getValue(apiSmartDevice, "apiBaseUrl", "api_base_url"));
                    formattedDevice.put("ai_model_id", getValue(apiSmartDevice, "aiModelId", "ai_model_id"));
                    formattedDevice.put("voice_type", getValue(apiSmartDevice, "voiceType", "voice_type"));
                    formattedDevice.put("voice_speed_ratio", getValue(apiSmartDevice, "voiceSpeedRatio", "voice_speed_ratio"));
                    formattedDevice.put("name", getValue(apiSmartDevice, "name", "name"));


                    log.info("从API获取并格式化智能体信息: {}", formattedDevice);
                    return formattedDevice;
                } else {
                    log.error("获取智能体信息失败: {}", responseBody);
                    return createDefaultSmartDevice(deviceId);
                }
            } catch (Exception e) {
                log.error("调用设备服务获取智能体信息失败: {}", e.getMessage());
                return createDefaultSmartDevice(deviceId);
            }
        } catch (Exception e) {
            log.error("获取智能体信息失败: {}", e.getMessage(), e);
            return createDefaultSmartDevice(deviceId);
        }
    }

    /**
     * 从Map中获取值，优先使用第一个key，如果为空则使用第二个key
     */
    private Object getValue(Map<String, Object> map, String key1, String key2) {
        Object value = map.get(key1);
        if (value != null) {
            return value;
        }
        return map.get(key2);
    }

    /**
     * 创建默认的智能体信息
     */
    private Map<String, Object> createDefaultSmartDevice(Long deviceId) {
        Map<String, Object> defaultDevice = new HashMap<>();
        defaultDevice.put("id", deviceId);
        // 使用与数据库一致的字段名
        defaultDevice.put("api_key", "f65fcf30-0c54-45ab-9fdc-e873c81f2fdf" + deviceId);
        defaultDevice.put("api_base_url", "https://ark.cn-beijing.volces.com/api/v3/bots/chat/completions");
        defaultDevice.put("ai_model_id", "bot-20250407204146-k6mps");
        defaultDevice.put("voice_type", "BV700_24k_streaming");
        defaultDevice.put("voice_speed_ratio", 1.2f);
        defaultDevice.put("name", "豆包");

        log.info("创建默认智能体配置: id={}, ai_model_id={}, api_key={}, voice_speed_ratio={}, name={}",
                deviceId,
                defaultDevice.get("ai_model_id"),
                defaultDevice.get("api_key"),
                defaultDevice.get("voice_speed_ratio"),
                defaultDevice.get("name"));

        return defaultDevice;
    }
}